home *** CD-ROM | disk | FTP | other *** search
/ Mac Mania 2 / MacMania 2.toast / Demo's / Tools&Utilities / Programming / SPIM Folder / Sources / mem.h < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-24  |  8.7 KB  |  251 lines  |  [TEXT/ttxt]

  1. /* SPIM S20 MIPS simulator.
  2.    Macros for accessing memory.
  3.    Copyright (C) 1990 by James Larus (larus@cs.wisc.edu).
  4.  
  5.    SPIM is free software; you can redistribute it and/or modify it
  6.    under the terms of the GNU General Public License as published by the
  7.    Free Software Foundation; either version 1, or (at your option) any
  8.    later version.
  9.  
  10.    SPIM is distributed in the hope that it will be useful, but WITHOUT
  11.    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12.    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13.    for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with GNU CC; see the file COPYING.  If not, write to James R.
  17.    Larus, Computer Sciences Department, University of Wisconsin--Madison,
  18.    1210 West Dayton Street, Madison, WI 53706, USA or to the Free
  19.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21.    A note on directions:  "Bottom" of memory is the direction of
  22.    decreasing addresses.  "Top" is the direction of increasing addresses.
  23.  
  24.    $Header: /var/home/cs354/.spim/RCS/mem.h,v 1.2 1992/10/07 04:08:04 cs354 Exp $
  25. */
  26.  
  27. #ifdef MEM_MAIN
  28. #define EXTERN
  29. #else
  30. #define EXTERN extern
  31. #endif
  32.  
  33. /* Type of contents of a memory word. */
  34.  
  35. typedef long mem_word;
  36.  
  37.  
  38. /* The text segment and boundaries. */
  39.  
  40. EXTERN instruction **text_seg;
  41.  
  42. EXTERN int text_modified;        /* Non-zero means text segment was written */
  43.  
  44. #define TEXT_BOT ((mem_addr) 0x400000)
  45.  
  46. EXTERN mem_addr text_top;
  47.  
  48.  
  49. /* Amount to grow text segment when we run out of space for instructions. */
  50.  
  51. #define TEXT_CHUNK_SIZE    4096
  52.  
  53.  
  54. /* The data segment and boundaries. */
  55.  
  56. EXTERN mem_word *data_seg;
  57.  
  58. EXTERN int data_modified;        /* Non-zero means a data segment was written */
  59.  
  60. EXTERN short *data_seg_h;        /* Points to same vector as DATA_SEG */
  61.  
  62. #ifdef ibm032
  63. #define BYTE_TYPE signed char
  64. #else
  65. #define BYTE_TYPE char
  66. #endif
  67.  
  68. EXTERN BYTE_TYPE *data_seg_b;        /* Ditto */
  69.  
  70. #define DATA_BOT ((mem_addr) 0x10000000)
  71.  
  72. EXTERN mem_addr data_top;
  73.  
  74. EXTERN mem_addr gp_midpoint;        /* Middle of $gp area */
  75.  
  76.  
  77. /* The stack segment and boundaries. */
  78.  
  79. EXTERN mem_word *stack_seg;
  80.  
  81. EXTERN short *stack_seg_h;        /* Points to same vector as STACK_SEG */
  82.  
  83. EXTERN BYTE_TYPE *stack_seg_b;        /* Ditto */
  84.  
  85. EXTERN mem_addr stack_bot;
  86.  
  87. /* Exclusive, but include 4K at top of stack. */
  88.  
  89. #define STACK_TOP ((mem_addr) 0x80000000)
  90.  
  91.  
  92. /* The kernel text segment and boundaries. */
  93.  
  94. EXTERN instruction **k_text_seg;
  95.  
  96. #define K_TEXT_BOT ((mem_addr) 0x80000000)
  97.  
  98. EXTERN mem_addr k_text_top;
  99.  
  100.  
  101. /* Kernel data segment and boundaries. */
  102.  
  103. EXTERN mem_word *k_data_seg;
  104.  
  105. EXTERN short *k_data_seg_h;
  106.  
  107. EXTERN BYTE_TYPE *k_data_seg_b;
  108.  
  109. #define K_DATA_BOT ((mem_addr) 0x90000000)
  110.  
  111. EXTERN mem_addr k_data_top;
  112.  
  113.  
  114.  
  115. instruction *funny_text_read ();
  116. void funny_text_write ();
  117. mem_word bad_mem_read ();
  118. void bad_mem_write ();
  119.  
  120.  
  121. /* You would think that a compiler could perform CSE on the arguments to
  122.    these macros.  However, complex expressions break some compilers, so
  123.    do the CSE ourselves. */
  124.  
  125. /* Translate from SPIM memory address to physical address */
  126.  
  127. #ifdef MACINTOSH
  128.  
  129. extern mem_addr MEM_ADDRESS(mem_addr addr);
  130.  
  131. #else
  132.  
  133. #define MEM_ADDRESS(ADDR)                           \
  134. (((mem_addr) (ADDR) >= TEXT_BOT && (mem_addr) (ADDR) < text_top)       \
  135.  ? (mem_addr) (ADDR) - TEXT_BOT + (mem_addr) text_seg               \
  136.  : (((mem_addr) (ADDR) >= DATA_BOT && (mem_addr) (ADDR) < data_top)       \
  137.     ? (mem_addr) (ADDR) - DATA_BOT + (mem_addr) data_seg           \
  138.     : (((mem_addr) (ADDR) >= stack_bot && (mem_addr) (ADDR) < STACK_TOP)   \
  139.        ? (mem_addr) (ADDR) - stack_bot + (mem_addr) stack_seg           \
  140.        : ((mem_addr) (ADDR) >= K_TEXT_BOT && (mem_addr) (ADDR) < k_text_top)\
  141.        ? (mem_addr) (ADDR) - K_TEXT_BOT + (mem_addr) k_text_seg           \
  142.        : (((mem_addr) (ADDR) >= K_DATA_BOT && (mem_addr) (ADDR) < k_data_top)\
  143.       ? (mem_addr) (ADDR) - K_DATA_BOT + (mem_addr) k_data_seg       \
  144.       : run_error ("Memory address out of bounds\n")))))
  145.  
  146. #endif
  147.  
  148. #define SET_MEM_INST(ADDR, INST)                       \
  149. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  150.    text_modified = 1;                               \
  151.    if (_addr_ >= TEXT_BOT && _addr_ < text_top && !(_addr_ & 0x3))       \
  152.      text_seg [(_addr_ - TEXT_BOT) >> 2] = INST;               \
  153.    else if (_addr_ >= K_TEXT_BOT && _addr_ < k_text_top && !(_addr_ & 0x3))\
  154.      k_text_seg [(_addr_ - K_TEXT_BOT) >> 2] = INST;               \
  155.    else funny_text_write (_addr_, INST);}
  156.  
  157.  
  158. #define SET_MEM_BYTE(ADDR, VALUE)                       \
  159. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  160.    data_modified = 1;                               \
  161.    if (_addr_ >= DATA_BOT && _addr_ < data_top)                   \
  162.      data_seg_b [_addr_ - DATA_BOT] = (unsigned char) (VALUE);           \
  163.    else if (_addr_ >= stack_bot && _addr_ < STACK_TOP)               \
  164.      stack_seg_b [_addr_ - stack_bot] = (unsigned char) (VALUE);       \
  165.    else if (_addr_ >= K_DATA_BOT && _addr_ < k_data_top)           \
  166.      k_data_seg_b [_addr_ - K_DATA_BOT] = (unsigned char) (VALUE);       \
  167.    else bad_mem_write (_addr_, VALUE, 0);}
  168.  
  169.  
  170. #define SET_MEM_HALF(ADDR, VALUE)                       \
  171. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  172.    data_modified = 1;                               \
  173.    if (_addr_ >= DATA_BOT && _addr_ < data_top && !(_addr_ & 0x1))       \
  174.      data_seg_h [(_addr_ - DATA_BOT) >> 1] = (unsigned short) (VALUE);       \
  175.    else if (_addr_ >= stack_bot && _addr_ < STACK_TOP && !(_addr_ & 0x1))  \
  176.      stack_seg_h [(_addr_ - stack_bot) >> 1] = (unsigned short) (VALUE);   \
  177.    else if (_addr_ >= K_DATA_BOT && _addr_ < k_data_top && !(_addr_ & 0x1))\
  178.      k_data_seg_h [(_addr_ - K_DATA_BOT) >> 1] = (unsigned short) (VALUE); \
  179.    else bad_mem_write (_addr_, VALUE, 0x1);}
  180.  
  181.  
  182. #define SET_MEM_WORD(ADDR, VALUE)                       \
  183. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  184.    data_modified = 1;                               \
  185.    if (_addr_ >= DATA_BOT && _addr_ < data_top && !(_addr_ & 0x3))       \
  186.      data_seg [(_addr_ - DATA_BOT) >> 2] = (mem_word) (VALUE);           \
  187.    else if (_addr_ >= stack_bot && _addr_ < STACK_TOP && !(_addr_ & 0x3))  \
  188.      stack_seg [(_addr_ - stack_bot) >> 2] = (mem_word) (VALUE);       \
  189.    else if (_addr_ >= K_DATA_BOT && _addr_ < k_data_top && !(_addr_ & 0x3))\
  190.      k_data_seg [(_addr_ - K_DATA_BOT) >> 2] = (mem_word) (VALUE);       \
  191.    else bad_mem_write (_addr_, VALUE, 0x3);}
  192.  
  193. #define READ_MEM_INST(LOC, ADDR)                       \
  194. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  195.    if (_addr_ >= TEXT_BOT && _addr_ < text_top && !(_addr_ & 0x3))       \
  196.      LOC = text_seg [(_addr_ - TEXT_BOT) >> 2];                   \
  197.    else if (_addr_ >= K_TEXT_BOT && _addr_ < k_text_top && !(_addr_ & 0x3))\
  198.      LOC = k_text_seg [(_addr_ - K_TEXT_BOT) >> 2];               \
  199.    else LOC = funny_text_read (_addr_);}
  200.  
  201.  
  202. #define READ_MEM_BYTE(LOC, ADDR)                       \
  203. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  204.    if (_addr_ >= DATA_BOT && _addr_ < data_top)                   \
  205.     LOC = data_seg_b [_addr_ - DATA_BOT];                   \
  206.    else if (_addr_ >= stack_bot && _addr_ < STACK_TOP)               \
  207.      LOC = stack_seg_b [_addr_ - stack_bot];                   \
  208.    else if (_addr_ >= K_DATA_BOT && _addr_ < k_data_top)           \
  209.     LOC = k_data_seg_b [_addr_ - K_DATA_BOT];                   \
  210.    else                                       \
  211.      LOC = bad_mem_read (_addr_, 0, (mem_word *) &LOC);}
  212.  
  213.  
  214. #define READ_MEM_HALF(LOC, ADDR)                       \
  215. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  216.    if (_addr_ >= DATA_BOT && _addr_ < data_top && !(_addr_ & 0x1))       \
  217.      LOC = data_seg_h [(_addr_ - DATA_BOT) >> 1];               \
  218.   else if (_addr_ >= stack_bot && _addr_ < STACK_TOP && !(_addr_ & 0x1))   \
  219.     LOC = stack_seg_h [(_addr_ - stack_bot) >> 1];               \
  220.    else if (_addr_ >= K_DATA_BOT && _addr_ < k_data_top && !(_addr_ & 0x1))\
  221.      LOC = k_data_seg_h [(_addr_ - K_DATA_BOT) >> 1];               \
  222.   else                                       \
  223.     LOC = bad_mem_read (_addr_, 0x1, (mem_word *) &LOC);}
  224.  
  225.  
  226. #define READ_MEM_WORD(LOC, ADDR)                       \
  227. {register mem_addr _addr_ = (mem_addr) (ADDR);                   \
  228.    if (_addr_ >= DATA_BOT && _addr_ < data_top && !(_addr_ & 0x3))       \
  229.      LOC = data_seg [(_addr_ - DATA_BOT) >> 2];                   \
  230.   else if (_addr_ >= stack_bot && _addr_ < STACK_TOP && !(_addr_ & 0x3))   \
  231.     LOC = stack_seg [(_addr_ - stack_bot) >> 2];               \
  232.    else if (_addr_ >= K_DATA_BOT && _addr_ < k_data_top && !(_addr_ & 0x3))\
  233.      LOC = k_data_seg [(_addr_ - K_DATA_BOT) >> 2];               \
  234.   else                                       \
  235.     LOC = bad_mem_read (_addr_, 0x3, (mem_word *) &LOC);}
  236.  
  237.  
  238. extern    void make_memory(long text_size,long data_size,long data_limit,
  239.     long stack_size,long stack_limit,long k_text_size,long k_data_size,
  240.     long k_data_limit);
  241. extern    void expand_data(long addl_bytes);
  242. extern    void expand_stack(long addl_bytes);
  243. extern    void expand_k_data(long addl_bytes);
  244. extern    instruction *funny_text_read(mem_addr addr);
  245. extern    void funny_text_write(mem_addr addr, instruction *inst);
  246. extern    mem_word bad_mem_read(mem_addr addr,int mask,mem_word *dest);
  247. extern    void bad_mem_write(mem_addr addr,mem_word value,int mask);
  248. extern    void print_mem(mem_addr addr);
  249.  
  250. #undef EXTERN
  251.